home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_100 / 105_01 / longcode.prn < prev    next >
Encoding:
Text File  |  1984-06-03  |  21.9 KB  |  434 lines

  1. LONG    MACRO-80 3.36    17-Mar-80    PAGE    1
  2.  
  3.  
  4.                                 ;                        LONG
  5.                                 ;
  6.                                 ;     LONG is a facility to allow long integers to be
  7.                                 ;   handled in BDS C.  A long integer is a four byte
  8.                                 ;   array with the least significant part of the integer
  9.                                 ;   stored in bytearray[0].  The integer is stored as a
  10.                                 ;   2's complement number with 31 bits of precision.
  11.                                 ;
  12.                                 ;     Operations supported by LONG include addition,
  13.                                 ;   subtraction, multiplication (least significant 31
  14.                                 ;   bits returned), division, and modulus.  Other
  15.                                 ;   operations, such as ascii to long, long to ascii,
  16.                                 ;   etc., can be programmed efficiently in C.
  17.                                 ;
  18.                                 ;     Calls to LONG are normally "wrapped up" in various
  19.                                 ;   C functions which, in turn, call the function
  20.                                 ;
  21.                                 ;        char *li(CODE,arg1,arg2,arg3)
  22.                                 ;        char CODE, *arg1, *arg2, *arg3;
  23.                                 ;
  24.                                 ;   which returns a pointer to the result.  Arg1, arg2,
  25.                                 ;   and arg3 must be pointers to four byte representations
  26.                                 ;   of long integers in the format defined above.  In
  27.                                 ;   general the operation performed is as if BDS C had
  28.                                 ;   a data type long and
  29.                                 ;
  30.                                 ;        long *arg1, *arg2, *arg3;
  31.                                 ;        *arg1 = *arg2 op *arg3;
  32.                                 ;
  33.                                 ;   where op is defined by the following table:
  34.                                 ;
  35.                                 ;         CODE     op      comment
  36.                                 ;
  37.                                 ;           0       +      signed 31 bit result
  38.                                 ;           1       -      signed 31 bit result
  39.                                 ;           2       *      signed low order 31 bit result
  40.                                 ;           3       /      signed 31 bit quotient
  41.                                 ;           4       %      positive 31 bit remainder
  42.                                 ;
  43.                                 ;   and, in each case, any overflow is both lost and not
  44.                                 ;   noted.
  45.                                 ;
  46.                                     TITLE    LONG
  47.                                 ;
  48.                                     PAGE    60
  49. LONG    MACRO-80 3.36    17-Mar-80    PAGE    1-1
  50.  
  51.  
  52.                                 
  53.                                 ;
  54.                                 ;   BDS C is copyright (c) 1980 by Leor Zolman.
  55.                                 ;   LONG is copyright (c) 1981 by Paul J. Gans.
  56.                                 ;
  57.                                 ;   A notable strangeness in the listing below is that
  58.                                 ;   my version of this assembler REQUIRES that the op
  59.                                 ;   code ex af,af' be CAPITOLIZED or it will not be
  60.                                 ;   recognized...-pjg.
  61.                                 ;
  62.                                     .z80
  63.                                 ;
  64.                                 ;     Note that the coding technique used here is basically
  65.                                 ;   that of William C. Colley, III as reported in the BDS C
  66.                                 ;   User's Guide Addenda, v1.32, dated May, 1980.  Note
  67.                                 ;   that Colley's technique is simplified by using the
  68.                                 ;   MACRO-80 pseudo-op DC to set the high order bit of
  69.                                 ;   the last character of a string.
  70.                                 ;
  71.   0000'                             aseg
  72.                                 ;
  73.                                     org    0000h
  74.                                 ;
  75.   0000    4C C9                     dc    'LI'    ; first directory entry
  76.   0002    0205                      dw    long
  77.                                 ;
  78.   0004    80                        db    80h    ; end of directory
  79.   0005    0336                      dw    f.free    ; next free file location
  80.                                 ;
  81.                                     org    0200h
  82.                                 ;
  83.   0200    00 00 00 00               db    0,0,0,0,0    ; always zero if no main
  84.   0204    00                    
  85.                                 ;
  86.   0205    00                    long:    db    0    ; no fn's called by LONG
  87.                                 ;
  88.   0206    0112                      dw    f.1rel-f.1beg    ; length of LONG
  89.                                 ;
  90.                                     .phase    0
  91.                                 ;
  92.                                 ;   At the start of this function the stack looks like:
  93.                                 ;       arg3, arg2, arg1, CODE, return address
  94.                                 ;   with the return address at the top of the stack.
  95.                                 ;
  96.   0000    D1                    f.1beg:    pop    de    ; DE=returnaddress
  97.   0001    E1                        pop    hl    ; CODE
  98.   0002    7D                        ld    a,l    ; A=CODE
  99.   0003    E1                        pop    hl    ; HL=arg1 (result address)
  100.   0004    DD E1                     pop    ix    ; IX=arg2
  101.   0006    FD E1                     pop    iy    ; IY=arg3
  102.   0008    E5                        push    hl    ; now restore the stack length
  103.   0009    E5                        push    hl
  104.   000A    E5                        push    hl
  105.   000B    E5                        push    hl
  106.   000C    D5                        push    de    ; restore return address
  107. LONG    MACRO-80 3.36    17-Mar-80    PAGE    1-2
  108.  
  109.  
  110.   000D    C5                        push    bc    ; save BC for caller
  111.   000E    E5                        push    hl    ; and a copy of arg1 for later
  112.                                 ;
  113.   000F    D9                        exx        ; goto prime register space
  114.   0010    FD 4E 00                  ld    c,(iy+0)    ; low order of args
  115.   0013    FD 46 01                  ld    b,(iy+1)
  116.   0016    DD 5E 00                  ld    e,(ix+0)
  117.   0019    DD 56 01                  ld    d,(ix+1)
  118.   001C    21 0000                   ld    hl,0    ; clear result
  119.                                 ;
  120.   001F    D9                        exx        ; goto normal register space
  121.   0020    FD 4E 02                  ld    c,(iy+2)    ; high order of args
  122.   0023    FD 46 03                  ld    b,(iy+3)
  123.   0026    DD 5E 02                  ld    e,(ix+2)
  124.   0029    DD 56 03                  ld    d,(ix+3)
  125.   002C    21 0000                   ld    hl,0    ; clear result
  126.                                 ;
  127.   002F    FE 00                     cp    0    ; check code
  128.   0031    CA 00AE               f.1001:    jp    z,add
  129.   0034    FE 01                     cp    1
  130.   0036    CA 00B7               f.1002:    jp    z,sub
  131.   0039    FE 02                     cp    2
  132.   003B    CA 0086               f.1003:    jp    z,mul
  133.                                 ;
  134.                                 ;   The division routine returns two possible values:
  135.                                 ;   the quotient, if CODE was 3, or the modulus, if
  136.                                 ;   CODE was 4.  As a sloppy error exit, CODEs higher
  137.                                 ;   than 4 or lower than 0 default to 4.  I SAID it
  138.                                 ;   was sloppy.
  139.                                 ;
  140.                                 ;   This routine expects a 64 bit dividend in registers
  141.                                 ;   HLH'L'DED'E' and a 32 bit divisor in registers BCB'C'.
  142.                                 ;   A 32 bit quotient is generated in DED'E' and a 32 bit
  143.                                 ;   remainder is generated in HLH'L'.  For the present
  144.                                 ;   application the high order 32 bits of the dividend
  145.                                 ;   (registers HLH'L') are zeroed.
  146.                                 ;
  147.                                 ;
  148.   003E    08                    div:    EX    AF,AF'    ; save CODE for later
  149.                                 ;
  150.                                 ;   Because signed divisions are a giant pain, the sign
  151.                                 ;   of the result is computed and saved on the stack.
  152.                                 ;   Then any negative operands are made positive via
  153.                                 ;   calls to the proper routine.
  154.                                 ;
  155.   003F    CD 00D7               f.1004:    call    sign
  156.                                 ;
  157.   0042    3E 20                     ld    a,32    ; number of iterations
  158.   0044    B7                    div1:    or    a    ; reset carry flag
  159.                                 ;
  160.   0045    D9                        exx        ; enter prime register space
  161.   0046    ED 42                     sbc    hl,bc    ; can we subtract?
  162.                                 ;
  163.   0048    D9                        exx        ; enter normal register space
  164.   0049    ED 42                     sbc    hl,bc
  165.   004B    30 05                     jr    nc,div2    ; a carry means no
  166. LONG    MACRO-80 3.36    17-Mar-80    PAGE    1-3
  167.  
  168.  
  169.                                 ;
  170.   004D    D9                        exx        ; enter prime register space
  171.   004E    09                        add    hl,bc    ; restore dividend
  172.                                 ;
  173.   004F    D9                        exx        ; enter normal register space
  174.   0050    ED 4A                     adc    hl,bc
  175.   0052    3F                    div2:    ccf        ; quotient bit
  176.                                 ;
  177.   0053    D9                        exx        ; enter prime register space
  178.   0054    CB 13                     rl    e    ; left shift dividend, shifting
  179.   0056    CB 12                     rl    d    ;   in new quotient bit as we go
  180.                                 ;
  181.   0058    D9                        exx        ; enter normal register space
  182.   0059    CB 13                     rl    e
  183.   005B    CB 12                     rl    d
  184.                                 ;
  185.   005D    D9                        exx        ; prime register space
  186.   005E    ED 6A                     adc    hl,hl    ; it's a 64 bit shift, guys
  187.                                 ;
  188.   0060    D9                        exx        ; normal register space
  189.   0061    ED 6A                     adc    hl,hl
  190.   0063    3D                        dec    a    ; done?
  191.   0064    F2 0044               f.1005:    jp    p,div1    ; no
  192.                                 ;
  193.                                 ;   CODE must now be tested so that HL can be set up
  194.                                 ;   properly.
  195.                                 ;
  196.   0067    08                        EX    AF,AF'    ; regain CODE
  197.   0068    FE 03                     cp    3
  198.   006A    20 0C                     jr    nz,modu    ; it's a modulus by default
  199.                                 ;
  200.   006C    D9                        exx        ; prime space
  201.   006D    EB                        ex    de,hl    ; return quotient
  202.                                 ;
  203.   006E    D9                        exx        ; normal space
  204.   006F    EB                        ex    de,hl
  205.   0070    F1                        pop    af    ; regain sign of result
  206.   0071    B7                        or    a    ; to flags
  207.   0072    FC 0104               f.1006:    call    m,neg1    ; if negative
  208.   0075    C3 00C2               f.1007:    jp    fin    ; to clean up and go home
  209.                                 ;
  210.   0078    CB 3C                 modu:    srl    h    ; adjust remainder for 1 bit
  211.   007A    CB 1D                     rr    l    ;   overshift
  212.                                 ;
  213.   007C    D9                        exx        ; prime space
  214.   007D    CB 1C                     rr    h
  215.   007F    CB 1D                     rr    l
  216.                                 ;
  217.   0081    D9                        exx        ; normal space
  218.   0082    D1                        pop    de    ; dump saved sign, mod is pos
  219.   0083    C3 00C2               f.1008:    jp    fin    ; to clean up and go home
  220.                                 ;
  221.                                 ;
  222.                                 ;   The multiplication routine multiplies the contents
  223.                                 ;   of registers BCB'C' by the contents of registers DED'E'
  224.                                 ;   and returns the low order 31 bits of the result in
  225. LONG    MACRO-80 3.36    17-Mar-80    PAGE    1-4
  226.  
  227.  
  228.                                 ;   registers HLH'L'.
  229.                                 ;
  230.                                 ;   Multiplication is also best done on positive numbers,
  231.                                 ;   so we go to the routine again.
  232.                                 ;
  233.   0086    CD 00D7               mul:    call    sign
  234.                                 ;
  235.   0089    3E 20                     ld    a,32
  236.                                 ;
  237.   008B    D9                    mul1:    exx        ; enter prime space
  238.   008C    CB 21                     sla    c    ; left shift plier 1 place
  239.   008E    CB 10                     rl    b
  240.                                 ;
  241.   0090    D9                        exx        ; enter normal space
  242.   0091    CB 11                     rl    c
  243.   0093    CB 10                     rl    b
  244.   0095    30 05                     jr    nc,mul2    ; if high bit was 0
  245.                                 ;
  246.   0097    D9                        exx        ; prime space
  247.   0098    19                        add    hl,de    ; add in multiplicand
  248.                                 ;
  249.   0099    D9                        exx        ; normal space
  250.   009A    ED 5A                     adc    hl,de
  251.   009C    3D                    mul2:    dec    a    ; done?
  252.   009D    28 07                     jr    z,mul3    ; yes, clean up and go home
  253.                                 ;
  254.   009F    D9                        exx        ; hyperspace
  255.   00A0    29                        add    hl,hl    ; left shift product
  256.                                 ;
  257.   00A1    D9                        exx        ; real space
  258.   00A2    ED 6A                     adc    hl,hl
  259.   00A4    18 E5                     jr    mul1    ; and repeat
  260.                                 ;
  261.   00A6    F1                    mul3:    pop    af    ; regain sign of result
  262.   00A7    B7                        or    a    ; sign to flags
  263.   00A8    FC 0104               f.1009:    call    m,neg1    ; if negative
  264.   00AB    C3 00C2               f.100a:    jp    fin    ; and so to rest at last...
  265.                                 ;
  266.                                 ;   The contents of BCB'C' are added to the contents of
  267.                                 ;   DED'E' and the results returned in HLH'L'.
  268.                                 ;
  269.   00AE    D9                    add:    exx        ; to prime
  270.   00AF    EB                        ex    de,hl
  271.   00B0    09                        add    hl,bc
  272.                                 ;
  273.   00B1    D9                        exx        ; to normal
  274.   00B2    EB                        ex    de,hl
  275.   00B3    ED 4A                     adc    hl,bc
  276.   00B5    18 0B                     jr    fin    ; to quit
  277.                                 ;
  278.                                 ;   The contents of BCB'C' are subtracted from the contents
  279.                                 ;   of DED'E' and the results returned in HLH'L'
  280.                                 ;
  281.   00B7    D9                    sub:    exx        ; to prime
  282.   00B8    B7                        or    a    ; reset carry flag
  283.   00B9    EB                        ex    de,hl
  284. LONG    MACRO-80 3.36    17-Mar-80    PAGE    1-5
  285.  
  286.  
  287.   00BA    ED 42                     sbc    hl,bc
  288.                                 ;
  289.   00BC    D9                        exx        ; to normal
  290.   00BD    EB                        ex    de,hl
  291.   00BE    ED 42                     sbc    hl,bc    
  292.   00C0    18 00                     jr    fin    ; to quit
  293.                                 ;
  294.                                 ;   This is the terminal section of code.  It stores the
  295.                                 ;   result from HLH'L' into the locations specified by
  296.                                 ;   arg1, restores BC and SP, and exits with HL containing
  297.                                 ;   arg1.
  298.                                 ;
  299.   00C2    DD E1                 fin:    pop    ix    ; IX=arg1 (result address)
  300.   00C4    C1                        pop    bc    ; restore BC while we are at it
  301.                                 ;
  302.   00C5    D9                        exx        ; to momentum space
  303.   00C6    DD 75 00                  ld    (ix+0),l
  304.   00C9    DD 74 01                  ld    (ix+1),h
  305.                                 ;
  306.   00CC    D9                        exx        ; to cartesian space
  307.   00CD    DD 75 02                  ld    (ix+2),l
  308.   00D0    DD 74 03                  ld    (ix+3),h
  309.   00D3    DD E5                     push    ix    ; get result address
  310.   00D5    E1                        pop    hl    ;   into HL
  311.                                 ;
  312.   00D6    C9                        ret        ; to real world
  313.                                 ;
  314.                                 ;   This subroutine computes the sign of the result in
  315.                                 ;   multiplication and division and saves it as bit 7 of
  316.                                 ;   the A register on the stack.  It also makes any
  317.                                 ;   negative operands positive.  Note that it assumes
  318.                                 ;   that HLH'L' are zeroed on entry.
  319.                                 ;
  320.   00D7    7A                    sign:    ld    a,d    ; contains sign of arg2
  321.   00D8    A8                        xor    b    ; generate result sign
  322.   00D9    DD E1                     pop    ix    ; save subs return address
  323.   00DB    F5                        push    af    ; save result sign
  324.                                 ;
  325.   00DC    7A                        ld    a,d    ; sign of arg2 again
  326.   00DD    B7                        or    a    ; to flags
  327.   00DE    F2 00EE               f.100b:    jp    p,sign1    ; if non-negative
  328.                                 ;
  329.                                 ;   Form the 2's complement of the second argument
  330.                                 ;   (DED'E').
  331.                                 ;
  332.   00E1    D9                        exx        ; far out space
  333.   00E2    AF                        xor    a    ; reset A and carry bit
  334.   00E3    ED 52                     sbc    hl,de
  335.   00E5    EB                        ex    de,hl    ; restore answer
  336.   00E6    6F                        ld    l,a    ; clean things up
  337.   00E7    67                        ld    h,a
  338.                                 ;
  339.   00E8    D9                        exx        ; home space
  340.   00E9    ED 52                     sbc    hl,de
  341.   00EB    EB                        ex    de,hl    ; more restore
  342.   00EC    6F                        ld    l,a    ; clean here too
  343. LONG    MACRO-80 3.36    17-Mar-80    PAGE    1-6
  344.  
  345.  
  346.   00ED    67                        ld    h,a
  347.                                 ;
  348.   00EE    78                    sign1:    ld    a,b    ; sign of arg3
  349.   00EF    B7                        or     a    ; to flags
  350.   00F0    F2 0102               f.100c:    jp    p,sign2    ; if non-negative
  351.                                 ;
  352.                                 ;   The two's complement of the third argument is formed
  353.                                 ;   in place (BCB'C').
  354.                                 ;
  355.   00F3    D9                        exx        ; prime
  356.   00F4    AF                        xor    a    ; reset A and carry
  357.   00F5    ED 42                     sbc    hl,bc
  358.   00F7    4D                        ld    c,l
  359.   00F8    44                        ld    b,h
  360.   00F9    6F                        ld    l,a    ; rezero things
  361.   00FA    67                        ld    h,a
  362.                                 ;
  363.   00FB    D9                        exx        ; normal
  364.   00FC    ED 42                     sbc    hl,bc
  365.   00FE    4D                        ld    c,l
  366.   00FF    44                        ld    b,h
  367.   0100    6F                        ld    l,a
  368.   0101    67                        ld    h,a
  369.                                 ;
  370.   0102    DD E9                 sign2:    jp    (ix)    ; that's all, folks!
  371.                                 ;
  372.                                 ;   This routine forms the 2's complement of the result
  373.                                 ;   in HLH'L'.
  374.                                 ;
  375.   0104    D9                    neg1:    exx        ; enter prime space
  376.   0105    AF                        xor    a    ; zero A and carry flag
  377.   0106    EB                        ex    de,hl
  378.   0107    6F                        ld    l,a    ; zero HL register
  379.   0108    67                        ld    h,a
  380.   0109    ED 52                     sbc    hl,de
  381.                                 ;
  382.   010B    D9                        exx        ; enter normal space
  383.   010C    EB                        ex    de,hl
  384.   010D    6F                        ld    l,a    ; zero HL register
  385.   010E    67                        ld    h,a
  386.   010F    ED 52                     sbc    hl,de
  387.                                 ;
  388.   0111    C9                        ret
  389.                                 ;
  390.   0112    000D                  f.1rel:    dw    (f.1end-$)/2    ; num of reloc params
  391.   0114    0032                      dw    f.1001+1    ; relocation addresses
  392.   0116    0037                      dw    f.1002+1
  393.   0118    003C                      dw    f.1003+1
  394.   011A    0040                      dw    f.1004+1
  395.   011C    0065                      dw    f.1005+1
  396.   011E    0073                      dw    f.1006+1
  397.   0120    0076                      dw    f.1007+1
  398.   0122    0084                      dw    f.1008+1
  399.   0124    0087                      dw    mul+1
  400.   0126    00A9                      dw    f.1009+1
  401.   0128    00AC                      dw    f.100a+1
  402. LONG    MACRO-80 3.36    17-Mar-80    PAGE    1-7
  403.  
  404.  
  405.   012A    00DF                      dw    f.100b+1
  406.   012C    00F1                  f.1end:    dw    f.100c+1
  407.                                 ;
  408.                                     .dephase
  409.                                 ;
  410.   0336                          f.free:            ; next free location
  411.                                 ;
  412.                                     end
  413. LONG    MACRO-80 3.36    17-Mar-80    PAGE    S
  414.  
  415.  
  416. Macros:
  417.  
  418. Symbols:
  419. ADD    00AE     DIV    003E     DIV1    0044     DIV2    0052 
  420. F.1001    0031     F.1002    0036     F.1003    003B     F.1004    003F 
  421. F.1005    0064     F.1006    0072     F.1007    0075     F.1008    0083 
  422. F.1009    00A8     F.100A    00AB     F.100B    00DE     F.100C    00F0 
  423. F.1BEG    0000     F.1END    012C     F.1REL    0112     F.FREE    0336 
  424. FIN    00C2     LONG    0205     MODU    0078     MUL    0086 
  425. MUL1    008B     MUL2    009C     MUL3    00A6     NEG1    0104 
  426. SIGN    00D7     SIGN1    00EE     SIGN2    0102     SUB    00B7 
  427.  
  428.  
  429.  
  430. No  Fatal error(s)
  431.  
  432.  
  433.                            end
  434. LONG    MACRO-80 3.36    17-